package entity

import (
	"src/zeus/iserver"

	log "src/zeus/logger"
)

const InvalidInstSvrID uint8 = 0xFF

// 脏属性分流器
type IDirtyPropertySorter interface {
	GetSorterType() EDPSorterType

	TryAddToDirtyList(p *PropInfo)

	HandlerForEach(consumeFunc func(p *PropInfo)) bool
	HandlerAllList(consumeListFunc func(list []*PropInfo) bool) bool

	ListCount() int
}

type IPropsContainer interface {
	iserver.IEntityProps

	InitProp(def *Def, interestSrvType uint8, subType string)
	InitProp2(def *Def, subType string)
	DestroyProp()
	GetPropIndex(name string) uint16
	GetPropRaw(name string) *PropInfo
	GetPropRaw2(index uint16) *PropInfo
	GetDef() *Def

	GetPropsCount() int
	// 遍历所有属性
	ForEachProp(callBack func(p *PropInfo))

	// 处理脏属性, 待处理列表空返回false, 处理完后会清空
	HandlerSorterResult(sorterType EDPSorterType, consumeFunc func(list []*PropInfo) bool) bool
	//根据是同步，还是保存，从里面拿到不同的脏数据
	HandlerSorterResultForeach(sorterType EDPSorterType, consumeFunc func(p *PropInfo)) bool

	GetDirtyPropSorter(sorterType EDPSorterType) IDirtyPropertySorter
	AddDirtyPropSorter(sorterType EDPSorterType) IPropsContainer
	DelDirtyPropSorter(sorterType EDPSorterType) IPropsContainer
	// 设置或替换分流器
	SetDirtyPropSorter(sorterType EDPSorterType, v IDirtyPropertySorter) IPropsContainer
}

type IPropDefProvider interface {
	GetPropDef(entityType string) *Def
}

/*
先从配置表里读出来，把本服务关心的这个类型的数据写到props和indexMap里
也就是名字关联和ID关联
然后再从redis里获取数据
*/
type PropsContainer struct {
	def   *Def                 //从文件加载进来的信息
	props map[uint16]*PropInfo //数据是空的从redis里读出来的数据都放在这里
	//props    []*PropInfo
	indexMap map[string]uint16 //数据名到ID
	//sorters  map[EDPSorterType]IDirtyPropertySorter
	sorters []IDirtyPropertySorter //这里有二个对象，一个是用来记录需要保存的数据，一个用来记录需要同步给别的服务器的东西
}

func NewPropsContainer() *PropsContainer {
	v := &PropsContainer{
		def:      nil,
		props:    make(map[uint16]*PropInfo),
		indexMap: make(map[string]uint16),
		sorters:  make([]IDirtyPropertySorter, 0, 2),
	}
	return v
}

// InitProp 初始化属性列表
func (e *PropsContainer) InitProp(def *Def, interestSrvType uint8, subType string) {
	if def == nil {
		return
	}

	e.def = def
	Sub := false
	if _, ok := e.def.NeedSubType[subType]; ok {
		Sub = true
	}

	for _, p := range e.def.Props {
		if Sub {
			if _, ok := p.SubTypes[subType]; !ok {
				continue
			}
		}
		if interestSrvType == InvalidInstSvrID { //如果本服务器是255服务器类型，就是全数据关心？
			e.addProp(p)
		} else {
			for _, s := range p.InterestSrvs {
				if s == interestSrvType {
					e.addProp(p)
					break
				}
			}
		}

	}

}

// InitProp 初始化属性列表
func (e *PropsContainer) InitProp2(def *Def, subType string) {
	if def == nil {
		return
	}

	e.def = def

	for _, p := range e.def.Props {
		if _, ok := p.SubTypes[subType]; !ok {
			continue
		} else {
			e.addProp(p)
		}
	}
}

// DestroyProp 销毁属性列表
func (e *PropsContainer) DestroyProp() {
	// e.props = nil
	// e.indexMap = nil
	// e.sorters = nil
}

func (e *PropsContainer) addProp(prop *PropDef) {
	e.props[prop.Index] = NewPropInfo(prop, e)
	e.indexMap[prop.Name] = prop.Index
}

// SetProp 设置一个属性的值
func (e *PropsContainer) SetProp(index uint16, v interface{}) {
	p, ok := e.props[index]
	if ok {
		p.SetValue(v)
	}
}

// GetProp 获取一个属生的值
func (e *PropsContainer) GetProp(index uint16) interface{} {
	p, ok := e.props[index]
	if !ok {
		log.Error("GetProp error. index ", index)
		return nil
	}
	return p.GetValue()
}

// GetProp 获取一个属生的值
func (e *PropsContainer) TryGetProp(index uint16) (interface{}, error) {
	p, ok := e.props[index]
	if !ok {
		return nil, ERROR_PROP_NOT_EXIST
	}
	return p.GetValue(), nil
}

// GetProp 获取一个属生的值
func (e *PropsContainer) IsDirty(index uint16, dType int8) bool {
	p, ok := e.props[index]
	if !ok {
		log.Error("IsDirty error. index ", index)
		return false
	}
	switch EDPSorterType(dType) {
	case EDPSorterTypeSync:
		return p.IsSyncDirty()
	case EDPSorterTypeSave:
		return p.IsSaveDirty()
	default:
		log.Error("IsDirty default error. index ", index)
		return false
	}
}

func (e *PropsContainer) GetPropIndex(name string) uint16 {
	return e.indexMap[name]
}

func (e *PropsContainer) GetPropRaw(name string) *PropInfo {
	prop, ok := e.props[e.GetPropIndex(name)]
	if !ok {
		log.Error("GetPropRaw error. ", name)
		return nil
	}
	return prop
}

func (e *PropsContainer) GetPropRaw2(index uint16) *PropInfo {
	prop, ok := e.props[index]
	if !ok {
		log.Error("GetPropRaw2 error. ", index)
		return nil
	}
	return prop
}
func (e *PropsContainer) GetDef() *Def {
	return e.def
}

// PropDirty 设置某属性为Dirty
func (e *PropsContainer) PropDirty(index uint16) {
	p := e.props[index]

	if p == nil {
		log.Error("PropDirty error. ", index)
		return
	}

	for _, sorter := range e.sorters {
		sorter.TryAddToDirtyList(p)
	}
}

// PropDirty2 设置某属性为指定的Dirty
func (e *PropsContainer) PropDirty2(index uint16, dType int8) {
	p := e.props[index]

	if p == nil {
		log.Error("PropDirty2 error. ", index, dType)
		return
	}
	for _, sorter := range e.sorters {
		if sorter.GetSorterType() == EDPSorterType(dType) {
			sorter.TryAddToDirtyList(p)
			break
		}
	}
}
func (e *PropsContainer) ForEachProp(callBack func(p *PropInfo)) {
	for _, p := range e.props {
		callBack(p)
	}
}

func (e *PropsContainer) GetPropsCount() int {
	return len(e.props)
}

func (e *PropsContainer) GetDirtyPropSorter(sorterType EDPSorterType) IDirtyPropertySorter {
	for _, sorter := range e.sorters {
		if sorter.GetSorterType() == sorterType {
			return sorter
		}
	}

	return nil
}
func (e *PropsContainer) AddDirtyPropSorter(sorterType EDPSorterType) IPropsContainer {
	for _, sorter := range e.sorters {
		if sorter.GetSorterType() == sorterType {
			return e
		}
	}
	if v := NewDirtyPropSorter(sorterType); v != nil {
		e.sorters = append(e.sorters, v)
	}
	return e
}

func (e *PropsContainer) DelDirtyPropSorter(sorterType EDPSorterType) IPropsContainer {
	for i, sorter := range e.sorters {
		if sorter.GetSorterType() == sorterType {
			e.sorters = append(e.sorters[:i], e.sorters[i+1:]...)
		}
	}

	return e
}

// 设置或替换分流器
func (e *PropsContainer) SetDirtyPropSorter(sorterType EDPSorterType, v IDirtyPropertySorter) IPropsContainer {
	for i, sorter := range e.sorters {
		if sorter.GetSorterType() == sorterType {
			e.sorters[i] = v
			return e
		}
	}
	e.sorters = append(e.sorters, v)
	return e
}

func (e *PropsContainer) HandlerSorterResultForeach(sorterType EDPSorterType, consumeFunc func(p *PropInfo)) bool {
	if sorter := e.GetDirtyPropSorter(sorterType); sorter != nil {
		return sorter.HandlerForEach(consumeFunc)
	}

	return false
}
func (e *PropsContainer) HandlerSorterResult(sorterType EDPSorterType, consumeFunc func([]*PropInfo) bool) bool {
	if sorter := e.GetDirtyPropSorter(sorterType); sorter != nil {
		return sorter.HandlerAllList(consumeFunc)
	}

	return false
}
